package com.hm.common.plugin.network.netty.su;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hm.common.plugin.network.netty.MessageSuport;
import com.hm.common.plugin.network.netty.vo.MessageResult;
import com.hm.common.plugin.network.netty.vo.ResponseMessage;
import com.hm.common.su.SpringBeanUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import lombok.extern.slf4j.Slf4j;

import java.text.MessageFormat;
import java.util.Iterator;
import java.util.Map;

/**
 * @author shishun.wang
 * @version 1.0
 * @date 2019/4/10 19:02
 * @describe
 */
@Slf4j
@ChannelHandler.Sharable
public class WebSocketServerHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
	
	/**
	 * 描述：读取完连接的消息后，对消息进行处理。
	 *      这里主要是处理WebSocket请求
	 */
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception {
		handlerWebSocketFrame(ctx, msg);
	}
	
	/**
	 * 描述：处理WebSocketFrame
	 * @param ctx
	 * @param frame
	 * @throws Exception
	 */
	private void handlerWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
		MessageSuport messageSuport = SpringBeanUtil.getBean(MessageSuport.class);
		if (frame instanceof BinaryWebSocketFrame){
			BinaryWebSocketFrame copy = (BinaryWebSocketFrame)frame.copy();
			
			MessageResult messageResult = messageSuport.messageExecute(copy.retain());
			messageResult.getChannelHandlerList().parallelStream().forEach(result ->{
				messageSuport.sendBinaryMessage(result,(BinaryWebSocketFrame) messageResult.getResult());
			});
		}else if(frame instanceof TextWebSocketFrame){
			String request = ((TextWebSocketFrame)frame).text();
			
			MessageResult messageResult = messageSuport.messageExecute(request);
			messageResult.getChannelHandlerList().parallelStream().forEach(result ->{
				messageSuport.sendTextMessage(result,(String) messageResult.getResult());
			});
		}
		
		/*if (frame instanceof BinaryWebSocketFrame){
			BinaryWebSocketFrame copy = (BinaryWebSocketFrame)frame.copy();
			*//*log.info("服务端收到新信息二进制数据：===========>"+copy);
			Iterator<Map.Entry<String, ChannelHandlerContext>> iterator =
					NettyChannelHandlerDef.onlineContent.entrySet().iterator();
			while(iterator.hasNext()) {
				Map.Entry<String, ChannelHandlerContext> entry = iterator.next();
				entry.getValue().channel().writeAndFlush(copy.retain());
			}*//*
		}else if(frame instanceof TextWebSocketFrame){
			String request = ((TextWebSocketFrame)frame).text();
			log.info("服务端收到新信息纯文本数据：===========>"+request);
			Iterator<Map.Entry<String, ChannelHandlerContext>> iterator =
					NettyChannelHandlerDef.onlineContent.entrySet().iterator();
			while(iterator.hasNext()) {
				Map.Entry<String, ChannelHandlerContext> entry = iterator.next();
				entry.getValue().channel().writeAndFlush(new TextWebSocketFrame(request));
			}
		}*/
	}
	
	/**
	 * 描述：客户端断开连接
	 */
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		Iterator<Map.Entry<String, ChannelHandlerContext>> iterator =
				NettyChannelHandlerDef.onlineContent.entrySet().iterator();
		while(iterator.hasNext()) {
			Map.Entry<String, ChannelHandlerContext> entry = iterator.next();
			if (entry.getValue() == ctx) {
				log.info("正在移除握手实例...");
				iterator.remove();
				log.info(MessageFormat.format("userId为 {0} 的用户已退出聊天，当前在线人数为：{1}"
						, entry.getKey(), NettyChannelHandlerDef.onlineContent.size()));
				break;
			}
		}
	}
	
	/**
	 * 异常处理：关闭channel
	 */
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		cause.printStackTrace();
		ctx.close();
	}
	
	
	private void sendMessage(ChannelHandlerContext ctx,ResponseMessage message) throws Exception{
		ctx.channel().writeAndFlush(new TextWebSocketFrame(new ObjectMapper().writeValueAsString(message)));
	}
}
